/*
Copyright (C) 1996-1997 GX Media, Inc.
Copyright (C) 2010 Ronie Salgado

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/

#ifndef QMAINFRAME_H
#define QMAINFRAME_H

#include "QProcessWindow.h"
#include "View.h"
#include "QooleId.h"
#include "QooleDoc.h"
#include "QooleOp.h"

class QTextureView;
class QTreeView;
class QPropSheet;
class QooleDoc;
struct MenuEntry;
class QMainFrame: public wxFrame
{
	DECLARE_DYNAMIC_CLASS(QMainFrame);
public:
	QMainFrame();
	~QMainFrame();

	bool Create(wxDocManager *manager);

	// Desktop documents
	QooleDoc *GetDeskTopDocument(void) const;
	void SetDeskTopDocument(QooleDoc *document);
	void UpdateFrameTitle(void);

	// Used by Undo/Redo.
	int GetUndoLevels(void) const { return opManager.GetUndoBufSize(); }
	void SetUndoLevels(int levels) { opManager.SetUndoBufSize(levels); }
	void CommitOperation(Operation &op);

	// ClipBoard
	LinkList<ObjectPtr> clipBoard;

	// Edit Focus and Locking Views.
	bool IsLockedView(QView *pView);
	const Vector3d &GetEditFocusPos(void) const { return editFocusPos; }

	void Set2DViewsLock(bool lock);
	void Set3DViewLock(bool lock);
	void Set2DLockedZoom(float newZoomVal, bool updateViews = true);
	void SetEditFocusPos(Vector3d &focusVec, bool updateViews = true);

	void GetLockedQViews(std::vector<QView*> &dest);
	void Get3DViews(std::vector<QView*> &dest);
	void GetViews(std::vector<QView*> &dest);

	// Operation modes
	OperationMode GetOpMode(void) const;
	OperationMode SwitchOpMode(OperationMode mode);

	// Desktop components
	bool QuadViews(bool createWnds = true);
	bool IsQViewValid(QView *view);
	void OnDestroyPropSheet(const wxRect &rect);
	void OnDestroyChild(wxPanel *child);

	// Scoping.
	Object &GetScope(void);
	Selector &GetSelector();
	Selector &ChangeEditScope(Object *newScope);

	// Panels.
	QProcessWindow *GetProcessWindow();
	QPropSheet *GetPropSheet();
	QTextureView *GetTextureView();
	QTreeView *GetTreeView();
	wxAuiNotebook *GetViewsNotebook();

	// Status bar.
	void UpdateStatusBar(const wxString &text, int id=0);
	void UpdateStatusBar();

	// Popup menus.
	wxMenu &GetAddObjectMenu() {return *pmView;}
	void BuildEntityMenus();

    // Extend event processing to search the document manager's event table
    virtual bool ProcessEvent(wxEvent& event);

	// Event handlers
    void OnExit(wxCommandEvent& WXUNUSED(event));
	void OnAbout(wxCommandEvent &event);
	void OnCloseWindow(wxCloseEvent& event);
	void OnLeftNotebook(wxAuiNotebookEvent &event);
	void OnDocumentPageChanged(wxAuiNotebookEvent &event);
	void OnDocumentPageClosed(wxAuiNotebookEvent &event);
	void OnMenuEntry(wxCommandEvent &event);

	// File menu
	void OnFileExportMap(wxCommandEvent &event);
	void OnFileExportMapUI(wxUpdateUIEvent &event);
	void OnFileCompileMap(wxCommandEvent &event);
	void OnFileCompileMapUI(wxUpdateUIEvent &event);
	void OnFileStopCompile(wxCommandEvent &event);
	void OnFileStopCompileUI(wxUpdateUIEvent &event);

	// Edit menu
	void OnEditUndo(wxCommandEvent &event);
	void OnEditUndoUI(wxUpdateUIEvent &event);
	void OnEditRedo(wxCommandEvent &event);
	void OnEditRedoUI(wxUpdateUIEvent &event);
	void OnEditCut(wxCommandEvent &event);
	void OnEditCutUI(wxUpdateUIEvent &event);
	void OnEditCopy(wxCommandEvent &event);
	void OnEditCopyUI(wxUpdateUIEvent &event);
	void OnEditPasteUI(wxUpdateUIEvent &event);
	void OnEditHollow(wxCommandEvent &event);
	void OnEditHollowUI(wxUpdateUIEvent &event);
	void OnEditDelete(wxCommandEvent &event);
	void OnEditDeleteUI(wxUpdateUIEvent &event);
	void OnEditSubtract(wxCommandEvent &event);
	void OnEditSubtractUI(wxUpdateUIEvent &event);
	void OnEditIntersect(wxCommandEvent &event);
	void OnEditIntersectUI(wxUpdateUIEvent &event);
	void OnEditPreferences(wxCommandEvent &event);
	void OnEditTextureManager(wxCommandEvent &event);

	// Mode menu
	void OnModeObjectMultiTool(wxCommandEvent &event);
	void OnModeObjectMultiToolUI(wxUpdateUIEvent &event);
	void OnModeObjectSelect(wxCommandEvent &event);
	void OnModeObjectSelectUI(wxUpdateUIEvent &event);
	void OnModeObjectMove(wxCommandEvent &event);
	void OnModeObjectMoveUI(wxUpdateUIEvent &event);
	void OnModeObjectRotate(wxCommandEvent &event);
	void OnModeObjectRotateUI(wxUpdateUIEvent &event);
	void OnModeObjectScale(wxCommandEvent &event);
	void OnModeObjectScaleUI(wxUpdateUIEvent &event);
	void OnModeFaceMove(wxCommandEvent &event);
	void OnModeFaceMoveUI(wxUpdateUIEvent &event);
	void OnModeEdgeMove(wxCommandEvent &event);
	void OnModeEdgeMoveUI(wxUpdateUIEvent &event);
	void OnModeVertexMove(wxCommandEvent &event);
	void OnModeVertexMoveUI(wxUpdateUIEvent &event);
	void OnModePlaneClip(wxCommandEvent &event);
	void OnModePlaneClipUI(wxUpdateUIEvent &event);
	void OnModeMirrorFlip(wxCommandEvent &event);
	void OnModeMirrorFlipUI(wxUpdateUIEvent &event);
	void OnModeEyeMove(wxCommandEvent &event);
	void OnModeEyeMoveUI(wxUpdateUIEvent &event);
	void OnModeEyeRotate(wxCommandEvent &event);
	void OnModeEyeRotateUI(wxUpdateUIEvent &event);
	void OnModeEyeZoom(wxCommandEvent &event);
	void OnModeEyeZoomUI(wxUpdateUIEvent &event);
	void OnModeFlyThroughPreview(wxCommandEvent &event);
	void OnModeFlyThroughPreviewUI(wxUpdateUIEvent &event);

	// Object menu
	void OnObjectProperties(wxCommandEvent &event);
	void OnObjectGroup(wxCommandEvent &event);
	void OnObjectGroupUI(wxUpdateUIEvent &event);
	void OnObjectUngroup(wxCommandEvent &event);
	void OnObjectUngroupUI(wxUpdateUIEvent &event);
	void OnObjectScopeUp(wxCommandEvent &event);
	void OnObjectScopeUpUI(wxUpdateUIEvent &event);
	void OnObjectScopeDown(wxCommandEvent &event);
	void OnObjectScopeDownUI(wxUpdateUIEvent &event);
	void OnObjectLoadPrefab(wxCommandEvent &event);
	void OnObjectLoadPrefabUI(wxUpdateUIEvent &event);
	void OnObjectSavePrefab(wxCommandEvent &event);
	void OnObjectSavePrefabUI(wxUpdateUIEvent &event);

	// Main frame window state.
	int wndMaximized;

	// Config states
	static int promptHollow;
	static int hollowThickness;
	static int promptGroupName;

	DECLARE_EVENT_TABLE();
private:
	// Toolbars.
	void CreateToolbars();

	// Popup Menus
	bool InitPopupMenus(void);
	void DestroyPopupMenus(void);
	void AddMenuEntry(wxMenu *menu, const wxChar *text, int type, const wxChar *data);
	void DeleteMenuEntry(int nID);
	wxMenu *CreateBrushMenu(void);
	void CreateEntityMenu(wxMenu &addMenu, wxMenu &applyMenu);
	wxMenu *ReadBrushCategory(wxXmlNode *category, wxMenu *parent);
	void BuildBrushMenu();

	// Functions to add objects.
	void LoadObject(const wxString &name);
	void AddEntity(const wxString &name);
	void ApplyEntity(const wxString &name);

	// Functions to keep track of the child views.
	wxPanel *GetActiveChild();
	void SetActiveChild(wxPanel *panel);
	
	wxAuiManager auiManager;
	wxDocManager *docManager;

	// Windows and special views.
	QProcessWindow *processWindow;
	QTextureView *textureView;
	QTreeView *treeView;
	QPropSheet *propSheet;
	wxAuiNotebook *documentViews;
	wxRect propSheetRect;

	// Desktop
	QooleDoc *desktopDocument;

	// Operation modes
	OperationMode operationMode;
	OpManager opManager;

	// Locked Views and Edit Focus.
	void FocusAllQViews(const Vector3d &centerVec, bool updateViews = true);

	Vector3d editFocusPos;
	bool lock2dViews, lock3dView;

	// Scope and object selector
	Object *editScope;
	Selector *selector;

	// View menu stuffs
	bool displayEntities;

	// Popup menus
	wxMenu *pmView;
	MenuEntry *menuEntry[QID_MENUENTRY_END - QID_MENUENTRY_START];
	int menuEntryCount;

	// Config
	LConfig *cfg;
	int undoLevels;
};

QMainFrame* GetMainFrame();

/// MenuEntry
/// Used to handle popup menu entries
struct MenuEntry
{
	int type;
	wxString data;
};

/// QViewsState
/// Used to remember the state of the QViews in QMainFrame.
class QViewsState {
public:
	QViewsState(void);
	virtual ~QViewsState();

	void RestoreQViewsState(void);

private:
	struct ViewState
	{
		QView *view;
		Vector3d position;
		SphrVector orientation;
		float zoom;
	};

	std::vector<ViewState> viewStates;
};

#endif //QMAINFRAME_H
